package qeug.shsh.task;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import kd.bos.context.RequestContext;
import kd.bos.dataentity.entity.DynamicObject;
import kd.bos.dataentity.entity.DynamicObjectCollection;
import kd.bos.entity.AppInfo;
import kd.bos.entity.AppMetadataCache;
import kd.bos.entity.MainEntityType;
import kd.bos.entity.flex.FlexEntireData;
import kd.bos.entity.flex.FlexEntityMetaUtils;
import kd.bos.entity.flex.FlexProperty;
import kd.bos.entity.operate.result.OperationResult;
import kd.bos.entity.param.AppCustomParam;
import kd.bos.entity.property.FlexProp;
import kd.bos.exception.KDException;
import kd.bos.flex.FlexService;
import kd.bos.orm.ORM;
import kd.bos.orm.query.QFilter;
import kd.bos.schedule.executor.AbstractTask;
import kd.bos.servicehelper.BusinessDataServiceHelper;
import kd.bos.servicehelper.operation.SaveServiceHelper;
import kd.bos.servicehelper.parameter.SystemParamServiceHelper;
import okhttp3.*;
import qeug.shsh.helper.FacadeHelper;
import scala.Int;

import java.io.IOException;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.util.*;
import java.util.stream.Collectors;

import static qeug.shsh.helper.FacadeHelper.getSAPAPI;


public class CCSSaveVoucherTaskPlugin extends AbstractTask {
    @Override
    public void execute(RequestContext requestContext, Map<String, Object> map) throws KDException {
        try {
            QFilter[] q1 = new QFilter[]{new QFilter("qeug_issap", "=", true)};
            DynamicObject[] bosOrgs = BusinessDataServiceHelper.load("bos_org", "qeug_issap,id,number", q1);
            List<String> orgNum =new ArrayList();
            for (DynamicObject bosOrg : bosOrgs) {
                orgNum.add(bosOrg.getString("number"));
            }
            // 获取当前日期
            LocalDate currentDate = LocalDate.now();
            // 获取当前年并转换为字符串
            String currentYear = String.valueOf(currentDate.getYear());
            // 获取当前月并转换为字符串，若为个位数则不显示前面的 0
            int monthValue = currentDate.getMonthValue();
            String currentMonth = String.valueOf(monthValue);
            String url=  System.getProperty("sapacc.url");
            String basicAuthUserName = "ccsuser";
            HashMap<String, Object> log = new HashMap<>();
            log.put("operationModule", "自动抽取凭证与物料费用");
            log.put("url", url);
            log.put("user", basicAuthUserName);
            log.put("mode", "POST");
            log.put("action", "");
            log.put("opdate", new Date());
            //根据应用编码从缓存中获取应用信息
            AppInfo cgfwAppInfo = AppMetadataCache.getAppInfo("gl");
            //获取应用的主键
            String appId = cgfwAppInfo.getId();
            AppCustomParam appCustomParam = new AppCustomParam(appId);
            Map<String, String> cusTomMap = SystemParamServiceHelper.loadAppCustomParameterFromCache(appCustomParam);
            for (int i = 0; i < orgNum.size(); i++) {
                for (int j = 0; j < cusTomMap.size(); j++) {
                    String kjkm = cusTomMap.get(j);
                    JSONObject body = new JSONObject();
                    body.put("BUKRS", orgNum.get(i));
                    body.put("GJAHR", currentYear);
                    body.put("MONAT", currentMonth);
                    body.put("RACCT", kjkm);
                    String sapapi = getSAPAPI(body.toJSONString(), url);
                    JSONArray voucher = FacadeHelper.getVoucher(sapapi);
                    String result = createVoucherStructure(voucher);
                    log.put("mainstring", body.toJSONString());
                    log.put("responsebody", sapapi);
                    JSONObject date = JSONObject.parseObject(result).getJSONObject("date");
                    int failCount = Integer.parseInt(date.getString("failCount"));
                    if (failCount > 0) {
                        log.put("pdesc", "失败");
                        log.put("operating_mode", date.getJSONArray("result"));
                        FacadeHelper.apiLog(log);
                    } else {
                        log.put("pdesc", "成功");
                        FacadeHelper.apiLog(log);

                    }
                }
            }
        } catch (ParseException e) {
            throw new RuntimeException(e);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }


    // 通过单个JSON生成单个核算维度组合ID，此处可以抽取为service方法
    private long saveFlexData(JSONObject json) {
        if (json == null || json.isEmpty()) {
            // 组合为空，核算维度ID默认为0
            return 0L;
        }
        // 通过弹性域的接口进行保存
        return FlexService.saveFlexData(getMainEntityType(), buildFlexEntireData(json));
    }

    private FlexEntireData buildFlexEntireData(JSONObject json) {
        FlexEntireData flexEntireData = new FlexEntireData();
        // 将json组装成flexEntireData
        flexEntireData.setFlexDatas(
                json.entrySet().stream().map(
                        e -> {
                            // 每个key-value创建一个FlexData
                            // 通过FlexField查找维度类型对象
                            FlexProperty flexProperty = FlexEntityMetaUtils.getFlexProperty(e.getKey());
                            FlexEntireData.FlexData flexData = flexEntireData.new FlexData(flexProperty, e.getValue());
                            // 根据维度类型设置值类型 基础资料、辅助资料、文本类型
                            FlexEntireData.FlexFieldDataType flexFieldDataType = FlexProp.TEXTVALUETYPE.equals(flexProperty.getValueType())
                                    ? FlexEntireData.FlexFieldDataType.STRING : FlexEntireData.FlexFieldDataType.LONG;
                            flexData.setDbType(flexFieldDataType);
                            return flexData;
                        }
                ).collect(Collectors.toList())
        );
        return flexEntireData;
    }

    private MainEntityType getMainEntityType() {
        // 默认写法
        MainEntityType mainEntityType = new MainEntityType();
        mainEntityType.setAlias("t_gl_assist");
        mainEntityType.setDBRouteKey("gl");
        return mainEntityType;
    }


    public static String createVoucherStructure(JSONArray jsonArray) throws ParseException, IOException {
//        String voucher = sapService.getVoucher(body.toJSONString());;
        JSONObject root = new JSONObject(new LinkedHashMap<>());
        JSONArray dataArray = new JSONArray();
        for (int i = 0; i < jsonArray.size(); i++) {
            boolean isMater = false;
            boolean isAccountview = true;
            DynamicObject materialCostBill = ORM.create().newDynamicObject("qeug_materialcostbill");
            JSONObject sapInfo = jsonArray.getJSONObject(i);
            String BUKRS = sapInfo.getString("BUKRS");//公司代码
            DynamicObject company = FacadeHelper.getDynamicObject("bos_org", "number", BUKRS);
                        String GJAHR = sapInfo.getString("GJAHR");//年度
//            String GJAHR = "2024";//年度
            String MONAT = sapInfo.getString("MONAT");//期间
            DynamicObject period = FacadeHelper.getDynamicObject("bd_period", "number", GJAHR + MONAT);
            String BELNR = sapInfo.getString("BELNR");//凭证编号
            String BLDAT = sapInfo.getString("BLDAT");//业务日期
            String bizDate = new SimpleDateFormat("yyyy-MM-dd").format(new SimpleDateFormat("yyyyMMdd").parse(BLDAT));
            String BUDAT = sapInfo.getString("BUDAT");//记账日期
            String jzDate = new SimpleDateFormat("yyyy-MM-dd").format(new SimpleDateFormat("yyyyMMdd").parse(BUDAT));
            SimpleDateFormat sf = new SimpleDateFormat();
            sf.applyPattern("yyyy-mm-dd");
//            Date bizDate = sf.parse(BLDAT);
//            Date jzDate = sf.parse(BUDAT);
            String BLART = sapInfo.getString("BLART");//凭证类型
//                        DynamicObject vouchertype = FacadeHelper.getDynamicObject("gl_vouchertype", "number", BLART);
            DynamicObject vouchertype = FacadeHelper.getDynamicObject("gl_vouchertype", "number", "0001");
//            String BELNR = sapInfo.getString("BELNR");//凭证号
            String SNAME = sapInfo.getString("SNAME");//制单人

//                        DynamicObject user = FacadeHelper.getDynamicObject("bos_user", "number", SNAME);
            DynamicObject user = FacadeHelper.getDynamicObject("bos_user", "number", "18115209696");
            String KURSF = sapInfo.getString("KURSF");//汇率
            String WAERS = sapInfo.getString("WAERS");//币别代码
            DynamicObject currency = FacadeHelper.getDynamicObject("bd_currency", "number", "CNY");
            String BKTXT = sapInfo.getString("BKTXT");//凭证抬头文本
            String STJAH = sapInfo.getString("STJAH");//冲销年度
            String STBLG = sapInfo.getString("STBLG");//冲销由（冲销凭证号）
            String XBLNR = sapInfo.getString("XBLNR");//参考信息
            String AWKEY = sapInfo.getString("AWKEY");//对象键值

            // 构建 DataItem
            JSONObject dataItem = new JSONObject(true);
            dataItem.put("org_number", BUKRS);
            dataItem.put("booktype_number", "100001");
            dataItem.put("period_number", period.getString("number"));
            dataItem.put("billno", BELNR);
            dataItem.put("billstatus", "A");
            dataItem.put("vouchertype_number", "0001");
            dataItem.put("vdescription", BKTXT);
            dataItem.put("bizdate", bizDate);
            dataItem.put("bookeddate", jzDate);
            dataItem.put("description", XBLNR);
            dataItem.put("attachment", 0);
            dataItem.put("creator_number", "SAP");
            dataItem.put("createtime", new Date());
            materialCostBill.set("billno", BELNR + BUKRS + GJAHR);//单据编号
            materialCostBill.set("billstatus", "A");//单据状态
            materialCostBill.set("creator", BELNR + BUKRS + GJAHR);//创建人
            materialCostBill.set("org", company);//组织
            materialCostBill.set("qeug_billtype", FacadeHelper.getDynamicObject("bos_billtype", "number", "qeug_materialcostbill_wl"));//
            materialCostBill.set("qeug_bizdate", new SimpleDateFormat("yyyyMMdd").parse(BLDAT));//业务日期
            DynamicObjectCollection materialCostEntrys = materialCostBill.getDynamicObjectCollection("entryentity");
            JSONArray voucherItem = sapInfo.getJSONArray("items");
            JSONArray entriesArray = new JSONArray();
            for (int j = 0; j < voucherItem.size(); j++) {
                JSONObject voucherentry = voucherItem.getJSONObject(j);
                //明细
                String DOCLN = voucherentry.getString("DOCLN").trim();//凭证行项目编号
                String SGTXT = voucherentry.getString("SGTXT");//凭证行项目文本
                String RACCT = voucherentry.getString("RACCT");//科目代码
                DynamicObject accountview = FacadeHelper.getDynamicObject("bd_accountview", "qeug_sapnumber", RACCT);
                if (accountview != null) {
                    RACCT = accountview.getString("number");
                } else {
                    isAccountview = false;
                    continue;
                }
//                DynamicObject accountview = FacadeHelper.getDynamicObject("bd_accountview", "number", "1221.02");
                String MATNR = voucherentry.getString("MATNR");//物料号
                String WSL = voucherentry.getString("WSL").trim();//以交易货币计的金额
                String DRCRK = voucherentry.getString("DRCRK");//借/贷标识
                String RCNTR = voucherentry.getString("RCNTR");//成本中心代码
                DynamicObject bos_costcenter = FacadeHelper.getDynamicObject("bos_costcenter", "number", RCNTR);
                String AUFNR = voucherentry.getString("AUFNR");//内部订单号
                String ZZFZHS02 = voucherentry.getString("ZZFZHS02");//辅助核算02
                String ZZFZHS03 = voucherentry.getString("ZZFZHS03");//辅助核算03
                // 构建 Entries

                JSONObject entry = new JSONObject(true);
                entry.put("seq", Integer.valueOf(DOCLN));

                if (DRCRK.equals("S")) {//jie
                    entry.put("debitori", new BigDecimal(FacadeHelper.formatNumber(WSL)));
                    entry.put("debitlocal", new BigDecimal(FacadeHelper.formatNumber(WSL)));
                    entry.put("creditori", BigDecimal.ZERO);
                    entry.put("creditlocal", BigDecimal.ZERO);
                } else if (DRCRK.equals("H")) {//dai
                    entry.put("creditori", new BigDecimal(FacadeHelper.formatNumber(WSL)));
                    entry.put("creditlocal", new BigDecimal(FacadeHelper.formatNumber(WSL)));
                    entry.put("debitori", BigDecimal.ZERO);
                    entry.put("debitlocal", BigDecimal.ZERO);
                }
                entry.put("localrate", BigDecimal.ONE);
//                entry.put("price", BigDecimal.ZERO);
                entry.put("edescription", SGTXT);
//                entry.put("quantity", BigDecimal.ZERO);
//                entry.put("maincfamount", BigDecimal.ZERO);
//                entry.put("suppcfamount", BigDecimal.ZERO);
                entry.put("currency_number", "CNY");
                entry.put("account_number", RACCT);

                // 构建 assgrp
                JSONObject assGrp = new JSONObject(true);
//                assGrp.put("id", "700017576538920960");
                assGrp.put("订单编号", AUFNR);
                JSONObject baseMaterial2 = new JSONObject(true);
//                baseMaterial2.put("id", "8923874751601479680");
//                baseMaterial2.put("name", "k7hZv");
                baseMaterial2.put("number", RCNTR);
                assGrp.put("成本中心", baseMaterial2);
//                assGrp.put("弹性域名称-辅助资料类型", baseMaterial2.clone());
                entry.put("assgrp", assGrp);
                entriesArray.add(entry);
                DynamicObject expInfo = new DynamicObject();
                if (MATNR != null) {
                    isMater = true;
                    expInfo = getExpInfo(MATNR);
                    DynamicObject materialCostEntry = materialCostEntrys.addNew();
                    materialCostEntry.set("qeug_accountview", accountview);//会计科目
                    materialCostEntry.set("qeug_expenseitemedit", expInfo);//费用项目
                    materialCostEntry.set("qeug_costcenter", bos_costcenter);//成本中心
                    QFilter[] q1 = new QFilter[]{new QFilter("costcenter.number", "=", RCNTR)};
                    DynamicObject costcentersourcemap = BusinessDataServiceHelper.loadSingle("bos_costcentersourcemap", q1);
                    if (costcentersourcemap != null) {
                        DynamicObject org = costcentersourcemap.getDynamicObjectCollection("entryentity").get(0).getDynamicObject("sourcedata");
                        materialCostEntry.set("qeug_org", org);//费用承担部门
                    }
                    materialCostEntry.set("qeug_supplies", MATNR);//物料号
                    materialCostEntry.set("qeug_suppliesmean", "");//物料描述
                    materialCostEntry.set("qeug_jdtype", DRCRK);//借贷方向
                    materialCostEntry.set("qeug_amount", new BigDecimal(FacadeHelper.formatNumber(WSL)));//金额
                }
            }
            dataItem.put("entries", entriesArray);
            dataItem.put("qeug_objectkey", AWKEY);
            dataItem.put("qeug_cxvoucher", STBLG);
            dataItem.put("sourcesystem_number", "SAP");
            if (!isMater && isAccountview) {
                dataArray.add(dataItem);
            } else {
                OperationResult operationResult = SaveServiceHelper.saveOperate("qeug_materialcostbill", new DynamicObject[]{materialCostBill}, null);
                System.out.println(operationResult);
            }
        }

        root.put("data", dataArray);
        OkHttpClient client = new OkHttpClient().newBuilder()
                .build();
        MediaType mediaType = MediaType.parse("application/json");
        RequestBody body = RequestBody.create(mediaType, root.toJSONString());
        Request request = new Request.Builder()
                .url("http://10.10.102.30:30088/ierp/kapi/v2/qeug/gl/gl_voucher/newsavevoucher")//uat
                .method("POST", body)
                .addHeader("access_token", FacadeHelper.getToken())
                .addHeader("Content-Type", "application/json")
                .build();
        Response response = client.newCall(request).execute();
        String string = response.body().string();
        System.out.println(string);
        return string;
    }

    public static DynamicObject getExpInfo(String matnr) {
        QFilter[] qFilters = new QFilter[]{new QFilter("qeug_suppliesnum", "=", matnr)};
        DynamicObject qeug_supplies_expense = BusinessDataServiceHelper.loadSingle("qeug_supplies_expense", qFilters);
        return qeug_supplies_expense.getDynamicObject("qeug_expense");
    }



}
